/**
 * Copyright (C), 2001-2031, www.bosssof.com.cn
 * FileName: RoleServiceImpl.java
 * Author: chen
 * Date: 2024/5/31 14:23
 * Description:
 * History:
 * Date Author Version Desc
 * 2024-01-01 bosssoft 1.0.0 initialize this file
 */
package com.bosssoft.g1.service.impl;

import cn.hutool.core.date.DateUtil;
import com.bosssoft.g1.common.annotation.CommonFieldStuffer;
import com.bosssoft.g1.common.annotation.MethodTypeEnum;
import com.bosssoft.g1.common.annotation.page.Pagination;
import com.bosssoft.g1.common.constant.EntityConsts;
import com.bosssoft.g1.common.exception.parse.BusinessException;
import com.bosssoft.g1.common.util.CommonResponseUtils;
import com.bosssoft.g1.common.util.service.AbstractBusinessService;
import com.bosssoft.g1.entity.*;
import com.bosssoft.g1.mapper.*;
import com.bosssoft.g1.dto.*;
import com.bosssoft.g1.dto.UserDTO;
import com.bosssoft.g1.query.RoleQuery;
import com.bosssoft.g1.query.UserRoleQuery;
import com.bosssoft.g1.service.RoleService;
import com.bosssoft.g1.utils.IdGenerator;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.page.PageMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import tk.mybatis.mapper.entity.Example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;

import static jdk.nashorn.internal.runtime.regexp.joni.Config.log;

/**
 * @className: RoleServiceImpl
 * @description:
 * 解决什么问题：
 * 主要方法：
 * methodxx
 * 注意事项：
 * @author: chen
 * @date: 2024/5/31 14:23
 * @since 1.0
 */
@Service
@Validated
public class RoleServiceImpl extends AbstractBusinessService implements RoleService {
    /**
     * 角色mapper
     */
    @Autowired
    private RoleMapper roleMapper;

    /**
     * 公司mapper
     */
    @Autowired
    private CompanyMapper companyMapper;

    /**
     * 资源mapper
     */
    @Autowired
    private ResourceMapper resourceMapper;

    /**
     * 组织mapper
     */
    @Autowired
    private OrganizationMapper organizationMapper;

    /**
     * 租户mapper
     */
    @Autowired
    private TenantMapper tenantMapper;

    /**
     * 用户mapper
     */
    @Autowired
    private UserMapper userMapper;

    /**
     * 角色资源mapper 对应basic_role_resource表
     */
    @Autowired
    private RoleResourceMapper roleResourceMapper;

    /**
     * 角色所处公司查询，一个角色可以属于多个公司
     */
    @Autowired
    private RoleCompanyMapper roleCompanyMapper;
    /**
     * 用户角色查询 对应 basic_user_role表
     */
    @Autowired
    private UserRoleMapper userRoleMapper;

    /**
     * id 生成器
     */
    @Autowired
    private IdGenerator idGenerator;

    private static final Logger log = LoggerFactory.getLogger(RoleServiceImpl.class);

    /**
     * 统一查询角色
     *
     * @param pageNum, pageSize
     * @return RoleDTO
     */
    @Pagination
    @CommonFieldStuffer(methodType = MethodTypeEnum.QUERY)
    @Override
    public PageInfo<RoleDTO> getAllRoles(Integer pageNum, Integer pageSize) {
        int offset = (pageNum - 1) * pageSize;
        // 查询总数
        int total = roleMapper.getTotalCount();
        // 分页查询
        List<RoleDTO> roles = roleMapper.getAllRoles(offset, pageSize);
        // 手动封装 PageInfo
        PageInfo<RoleDTO> pageInfo = new PageInfo<>(roles);
        pageInfo.setTotal(total);
        // 设置当前页码和页面大小
        pageInfo.setPageNum(pageNum);
        pageInfo.setPageSize(pageSize);
        // 计算总页数
        int pages = (int) Math.ceil((double) total / pageSize);
        pageInfo.setPages(pages);
        return pageInfo;
    }

    /**
     * 增加角色
     *
     * @param roleDTO
     * @return
     */
    @Override
    public Boolean addRole(@NotNull @Valid RoleDTO roleDTO) {
        //检查角色的编号是否已经存在
        if(roleMapper.roleExistByRoleCode(roleDTO.getCode())){
            log.warn("Role with code {} already exists.", roleDTO.getCode());
            throw new BusinessException(String.valueOf(-2L),"该角色编号已存在");
        }

        roleDTO.setCreatedTime(DateUtil.parse(DateUtil.now()));
        Role role = convertToRoleEntity(roleDTO);
        role.setId(idGenerator.snowflakeId());
        log.debug("Role to be inserted: {}" , role);

        return roleMapper.insertRole(role) > 0;
    }

    /**
     * 通过角色id进行删除操作
     * 涉及到 角色表，角色资源表，用户角色表
     *
     * @param id
     * @return Boolean
     */
    @Override
    @Transactional
    public Boolean deleteRoleById(@NotNull @Valid Long id) {
        // 构建 Example 查询条件
        Example example = new Example(Role.class);
        example.createCriteria().andEqualTo("id", id);

        // TODO 直接selectByPrimaryKey
        // 查询 Role 实体
        List<Role> roles = roleMapper.selectByExample(example);
        if (roles.isEmpty()) {
            throw new BusinessException(String.valueOf(id), "Role not found with the id");
        }

        // 删除角色资源表相关信息
        Example exampleRoleResource = new Example(RoleResource.class);
        exampleRoleResource.createCriteria().andEqualTo("roleId", id);
        roleResourceMapper.deleteByExample(exampleRoleResource);

        // 删除角色用户表相关信息
        Example exampleUserRole = new Example(UserRole.class);
        exampleUserRole.createCriteria().andEqualTo("roleId", id);
        userRoleMapper.deleteByExample(exampleUserRole);

        // 删除角色表相关信息
        Example exampleRole = new Example(Role.class);
        exampleRole.createCriteria().andEqualTo("id", id);

        return roleMapper.deleteByExample(exampleRole) > 0;
    }

    /**
     * 通过roleDTO进行批量删除操作
     * 涉及到 角色表，角色资源表，用户角色表
     *
     * @param roleDTO
     * @return Boolean
     */
    @Transactional
    @CommonFieldStuffer(methodType = MethodTypeEnum.DELETE)
    @Override
    public Boolean batchDeleteRole(@NotEmpty @Valid List<RoleDTO> roleDTO) {
        for (RoleDTO dto : roleDTO) {
            Long id = dto.getId();
            // 打印调试信息
            log.debug("Querying role with ID: {}", id);

            if (id == null || id <= 0) {
                throw new BusinessException("Invalid role ID: " + id);
            }

            // 构建 Example 查询条件
            Example example = new Example(Role.class);
            example.createCriteria().andEqualTo("id", id);

            // 查询 Role 实体
            List<Role> roles = roleMapper.selectByExample(example);
            if (roles.isEmpty()) {
                throw new BusinessException("Role not found with the id: " + id);
            }

            // 删除角色资源表相关信息
            Example exampleRoleResource = new Example(RoleResource.class);
            exampleRoleResource.createCriteria().andEqualTo("roleId", id);
            roleResourceMapper.deleteByExample(exampleRoleResource);

            // 删除角色用户表相关信息
            Example exampleUserRole = new Example(UserRole.class);
            exampleUserRole.createCriteria().andEqualTo("roleId", id);
            userRoleMapper.deleteByExample(exampleUserRole);

            // 删除角色公司表相关信息
            Example exampleRoleCompany = new Example(RoleCompany.class);
            exampleRoleCompany.createCriteria().andEqualTo("roleId", id);
            roleCompanyMapper.deleteByExample(exampleRoleCompany);

            // 删除角色表相关信息
            roleMapper.deleteByExample(example);
        }
        return true;
    }

    /**
     * 通过角色id查询单个角色
     * @param id
     * @return RoleDTO
     */
    @Override
    public RoleDTO queryRoleById( Long id) {
        Role role = roleMapper.selectByPrimaryKey(id);
        RoleDTO roleDTO = new RoleDTO();
        BeanUtils.copyProperties(role, roleDTO);

        if (role != null) {
            // 初始化嵌套对象
            if (roleDTO.getCompanyDTO() == null) {
                roleDTO.setCompanyDTO(new CompanyDTO());
            }
            if (roleDTO.getOrganizationDTO() == null) {
                roleDTO.setOrganizationDTO(new OrganizationDTO());
            }
            if (roleDTO.getTenantDTO() == null) {
                roleDTO.setTenantDTO(new TenantDTO());
            }

            Company company = companyMapper.selectByPrimaryKey(role.getCompanyId());
            Organization organization = organizationMapper.selectByPrimaryKey(role.getOrgId());
            Tenant tenant = tenantMapper.selectByPrimaryKey(role.getTenantId());

            // 复制属性
            if (role.getCompanyId() != null) {
                BeanUtils.copyProperties(company, roleDTO.getCompanyDTO());
            }
            if (role.getOrgId() != null) {
                BeanUtils.copyProperties(organization, roleDTO.getOrganizationDTO());
            }
            if (role.getTenantId() != null) {
                BeanUtils.copyProperties(tenant, roleDTO.getTenantDTO());
            }
        }
        return roleDTO;
    }

    /**
     * 根据角色名查询角色信息，模糊查询
     * @param name
     * @return
     */
    @Override
    public PageInfo<RoleDTO> queryRoles(int pageSize, int pageNum, String name) {
        log.debug("Role query: {}", name);

        // 开始分页
        PageHelper.startPage(pageNum, pageSize);

        // 创建查询条件
        Example exampleRole = new Example(Role.class);
        exampleRole.setOrderByClause("updated_time DESC");
        Example.Criteria criteria = exampleRole.createCriteria();

        // 进行模糊查询
        if (StringUtils.hasText(name)) {
            criteria.andLike("name", "%" + name + "%");
        }

        // 执行查询
        List<Role> roles = roleMapper.selectByExample(exampleRole);

        // 将 Role 转换为 RoleDTO
        List<RoleDTO> roleDTOList = new ArrayList<>();
        for (Role role : roles) {
            RoleDTO roleDTO = new RoleDTO();
            BeanUtils.copyProperties(role, roleDTO);
            roleDTOList.add(roleDTO);
        }

        // 返回分页信息
        return new PageInfo<>(roleDTOList);
    }

    /**
     * 更新 编辑 角色信息
     * @param roleDTO
     * @return
     */
    @Override
    public Boolean updateRole(@NotNull @Valid RoleDTO roleDTO){
        //检查角色的编号是否已经存在
        if(roleMapper.roleExistByRoleCode(roleDTO.getCode())){
            log.warn("Role with code {} already exists.", roleDTO.getCode());
            throw new BusinessException(String.valueOf(-2L),"该角色编号已存在");
        }

        Role role = convertToRoleEntity(roleDTO);
        if (role == null) {
            throw new BusinessException("Role 未找到");
        }
        // Log the role and roleDTO objects
        log.info("Role object: {}" , role);
        log.info("RoleDTO object: {}",roleDTO);
        return roleMapper.updateByPrimaryKey(role) > 0;
    }

    /**
     * 通过角色id查询角色所拥有的资源树
     * @param id
     * @return
     */
    @Override
    public List<Node> queryRoleResourceByRoId(Long id){
        List<Long> resourceIds = roleResourceMapper.getResourceIdsByRoleId(id);
        return queryUserResourceByResourceId(resourceIds,false);
    }

    /**
     * 调用方法，生成资源树
     * @param resourceIds
     * @param flag
     * @return
     */
    public List<Node> queryUserResourceByResourceId(List<Long> resourceIds,boolean flag){
        // 创建一个Set来存储已添加的资源ID
        Set<Long> addedResourceIds = new HashSet<>();
        List<Resource> resources = new ArrayList<>();

        for (Long resourceId : resourceIds) {
            Resource resource = resourceMapper.queryResourceByResourceId(resourceId);
            if (resource != null && !addedResourceIds.contains(resource.getId())) {
                resources.add(resource);
                // 将资源ID添加到Set中
                addedResourceIds.add(resource.getId());
            }
        }

        // 打印原始资源列表以调试
        resources.forEach(resource ->
                log.info("原始资源: id={}, name={}, type={}", resource.getId(), resource.getName(), resource.getResourceType())
        );

        // 过滤掉 resourceType 为 1 的资源，确保类型转换正确
        List<Resource> filteredResources = resources.stream()
                .filter(resource -> resource.getResourceType() != (byte) 1)
                .collect(Collectors.toList());

        // 打印过滤后的资源列表以调试
        filteredResources.forEach(resource ->
                log.info("过滤后的资源： id={}, name={}, type={}",resource.getId(), resource.getName(), resource.getResourceType())
        );

        // 构建一个 Map，以 id 为键，Node 为值
        Map<Long, Node> nodeMap = new HashMap<>();

        // 首先创建所有的节点并放入 map 中
        for (Resource resource : filteredResources) {
            nodeMap.put(resource.getId(), new Node(resource.getId(), resource.getName(), resource.getResourceType(), flag));
        }

        // 创建一个列表来存放根节点
        List<Node> rootNodes = new ArrayList<>();

        // 遍历所有的资源，将每个资源添加到其父节点的 children 列表中
        for (Resource resource : filteredResources) {
            Node node = nodeMap.get(resource.getId());
            if (resource.getParentId() == 1 || resource.getParentId() == -1) {
                // 如果 parentId 是 1 或 -1，则认为是根节点
                rootNodes.add(node);
            } else {
                // 否则，将其添加到其父节点的 children 列表中
                Node parentNode = nodeMap.get(resource.getParentId());
                if (parentNode != null) {
                    parentNode.addChild(node);
                } else {
                    log.warn("未找到父节点，资源ID: id={}, 父ID: parentId={}",resource.getId(),resource.getParentId());
                }
            }
        }

        return rootNodes;
    }

    /**
     * 通过角色id查询角色所属公司
     * @param id
     * @return
     */
    @Override
    public List<CompanyDTO> queryRoleCompanyByRoId(Long id){
        return roleMapper.queryRoleCompanyByRoId(id);
    }

    /**
     * 通过用户id查询用户所拥有的资源（子系统）--资源分配1
     * @param userRoleQuery
     * @return
     */
    @Transactional
    @Override
    public List<Node> queryUserResourceByRole(@NotNull @Valid UserRoleQuery userRoleQuery) {
        // 检查参数是否为空
        if (userRoleQuery == null) {
            // 抛出异常
            throw new IllegalArgumentException("UserRoleQuery cannot be null");
        }

        Long userId = userRoleQuery.getUserId();
        Long roleId = userRoleQuery.getRoleId();

        // 生成特定角色ID对应的资源树
        List<Long> resourceIds = roleResourceMapper.getResourceIdsByRoleId(roleId);
        List<Node> roleResourcesTree = queryUserResourceByResourceId(resourceIds,true);
        if (roleResourcesTree == null) {
            // 抛出异常
            throw new IllegalArgumentException("roleResourcesTree cannot be null");
        } else {
            log.warn("roleResourcesTree is not null");
        }

        // 查询用户角色列表
        List<Long> roleIds = userRoleMapper.getRoleIdsByUserId(userId);

        // 生成用户所有资源树
        List<Node> userResourcesTree = generateUserResourcesTree(roleIds);
        if (userResourcesTree == null) {
            // 抛出异常
            throw new IllegalArgumentException("userResourcesTree cannot be null");
        }else{
            log.warn("userResourcesTree is not null");
        }
        // 将用户资源树合并到特定角色资源树中并去重
        mergeAndDeduplicateTrees(userResourcesTree, roleResourcesTree);

        // 返回最终的用户资源树
        return roleResourcesTree;
    }

    // 辅助方法：比较两个节点的children是否相同
    private boolean compareChildren(List<Node> children1, List<Node> children2) {
        if (children1.size() != children2.size()) {
            return false;
        }
        for (int i = 0; i < children1.size(); i++) {
            Node child1 = children1.get(i);
            Node child2 = children2.get(i);
            if (!child1.getId().equals(child2.getId()) || !child1.getName().equals(child2.getName())) {
                return false;
            }
        }
        return true;
    }

    // 合并用户资源树到特定角色资源树并去重
    private void mergeAndDeduplicateTrees(List<Node> userTree, List<Node> roleTree) {
        for (Node userNode : userTree) {
            // 打印用户资源树节点信息
            log.info("用户资源树节点: id={}, name={}, type={}", userNode.getId(), userNode.getName(), userNode.getResourceType());

            boolean found = false;
            for (Node roleNode : roleTree) {
                // 打印角色资源树节点信息
                log.info("角色资源树节点: id={}, name={}, type={}", roleNode.getId(), roleNode.getName(), roleNode.getResourceType());

                /*if (roleNode.getId().equals(userNode.getId()) &&
                        roleNode.getName().equals(userNode.getName()) &&
                        compareChildren(roleNode.getChildren(), userNode.getChildren())) {*/
                if (roleNode.getId().equals(userNode.getId()) &&
                        roleNode.getName().equals(userNode.getName())){
                    found = true;
                    // 合并子节点，保留角色资源树的信息
                    mergeAndDeduplicateTrees(userNode.getChildren(), roleNode.getChildren());
                    break;
                }
            }
            if (!found) {
                roleTree.add(userNode);
            }
        }
    }

    /**
     * 生成用户所有资源树
     * @param roleIds
     * @return List<Node>
     */
    private List<Node> generateUserResourcesTree(List<Long> roleIds) {
        // 使用 Set 来确保资源 ID 的唯一性
        Set<Long> uniqueResourceIds = new HashSet<>();

        // 遍历所有角色，获取每个角色对应的资源ID
        for (Long roleId : roleIds) {
            List<Long> roleResourceIds = roleResourceMapper.getResourceIdsByRoleId(roleId);
            uniqueResourceIds.addAll(roleResourceIds);
        }

        // 生成用户所有资源树
        return queryUserResourceByResourceId(new ArrayList<>(uniqueResourceIds),false);
    }

    /**
     * 显示公司信息
     * @return List<CompanyDTO>
     */
    @Override
    public List<CompanyDTO> getAllCompanies(){
        return companyMapper.getAllCompanies();
    }

    /**
     * 查询角色分配时的用户信息
     * @param pageDTO
     * @return PageInfo<UserDTO>
     */
    @Override
    public PageInfo<UserDTO> queryUsers(@NotNull @Valid PageDTO pageDTO){
        PageMethod.startPage(pageDTO.getPageNum(),pageDTO.getPageSize());
        List<UserDTO> userList=userMapper.queryUsers();
        return new PageInfo<>(userList);
    }

    /**
     * 角色分配2 进行用户的角色分配
     * @param userRoleDTO
     * @return Boolean
     */
    @Transactional
    @Override
    public Boolean assignUserToRole(@NotNull @Valid UserRoleDTO userRoleDTO) {
        log.info("Role IDs: {}, User IDs: {}", userRoleDTO.getRoleIds(), userRoleDTO.getUserIds());
        // 检查 idGenerator 对象是否为空
        if (idGenerator == null) {
            log.warn("IdGenerator 对象未正确注入，无法生成唯一标识。");
            return false;
        }

        // 检查 roleIds 和 userIds 是否为空
        if (userRoleDTO.getRoleIds() == null || userRoleDTO.getRoleIds().isEmpty()) {
            return false;
        }
        if (userRoleDTO.getUserIds() == null || userRoleDTO.getUserIds().isEmpty()) {
            return false;
        }

        List<Long> roleIds = new ArrayList<>(new HashSet<>(userRoleDTO.getRoleIds()));
        List<Long> userIds = new ArrayList<>(new HashSet<>(userRoleDTO.getUserIds()));

        Example example = new Example(UserRole.class);
        example.createCriteria().andIn("roleId", roleIds);
        userRoleMapper.deleteByExample(example);

        int insertRows = 0;
        for (Long roleId : roleIds) {
            UserRole userRole = new UserRole();
            userRole.setRoleId(roleId);
            userRole.setTenantId(1337940702788714496L);

            for (Long userId : userIds) {
                userRole.setId(idGenerator.snowflakeId());
                userRole.setUserId(userId);
                userRole.setCreatedBy(11L);
                userRole.setCreatedTime(new Date());

                // 添加日志以确保 createdTime 被正确设置
                if (userRole.getCreatedTime() == null) {
                    log.debug("createdTime is null for userId: {}", userId);
                } else {
                    log.info("createdTime is set for userId: {} - {}", userId, userRole.getCreatedTime());
                }

                userRole.setStatus((byte) EntityConsts.INITIAL_STATUS);
                userRole.setVersion(EntityConsts.INITIAL_VERSION);

                log.info("UserRole: {}", userRole);

                insertRows += userRoleMapper.insert(userRole);
            }
        }
        return insertRows > 0;
    }


    private Role convertToRoleEntity(RoleDTO roleDTO) {
        Role role = new Role();
        // 生成唯一ID的方法
        role.setId(roleDTO.getId());
        role.setName(roleDTO.getName());
        role.setCode(roleDTO.getCode());
        role.setRemark(roleDTO.getRemark());
        role.setTenantId(1337940702788714496L);
        role.setOrgId(1337955940401545216L);
        role.setCompanyId(1337960193258029056L);
        role.setCreatedBy(11L);
        role.setCreatedTime(DateUtil.parse(DateUtil.now()));
        role.setUpdatedBy(0L);
        role.setUpdatedTime(DateUtil.parse(DateUtil.now()));
        role.setStatus(roleDTO.getStatus());
        // 默认版本号
        role.setVersion(1L);
        return role;
    }

    /**
     * 获取公司对应的所有角色
     *
     * @param companyId
     */
    @Override
    public PageInfo<Role> getCompanyRoleList(Long companyId, Integer pageNum, Integer pageSize) {
        // 设置分页信息
        PageHelper.startPage(pageNum, pageSize);

        // 创建查询条件
        Example exampleRole = new Example(Role.class);
        Example.Criteria criteria = exampleRole.createCriteria();

        // 进行模糊查询
        if (companyId != null) {
            criteria.orEqualTo("companyId", companyId);
        }

        // 执行查询
        List<Role> roles = roleMapper.selectByExample(exampleRole);

        // 将查询结果封装到PageInfo对象中
        return new PageInfo<>(roles);
    }

    /**
     * 删除角色的所有的资源
     *
     * @param roleIds 角色id列表 不可以为空
     * @return Boolean
     */
    public Boolean batchdeleteRoleResourceByRoleId(List<Long> roleIds) {
        if (CollectionUtils.isEmpty(roleIds)) {
            throw new BusinessException("roleIds不可以为空");
        }
        // 进行角色分配，先删除后插入
        Example example = new Example(RoleResource.class);
        example.createCriteria().andIn("roleId", roleIds);
        int rowsAffected = roleResourceMapper.deleteByExample(example);
        return rowsAffected > 0;
    }

    /**
     * 资源分配——资源
     *
     * @param roleResourceDTO
     */
    @Transactional
    @Override
    public Boolean assignResourceToRole(@NotNull @Valid RoleResourceDTO roleResourceDTO){
        // 给角色分配多个资源 参数去重复
        Set<Long> roleIdSet = roleResourceDTO.getRoleIds().stream().collect(Collectors.toSet());
        List<Long> roleIds = CollectionUtils.arrayToList(roleIdSet.toArray());
        Set<Long> resourceSet = roleResourceDTO.getResourceIds().stream().collect(Collectors.toSet());
        List<Long> resourceIds = CollectionUtils.arrayToList(resourceSet.toArray());

        idGenerator.init();

        // 删除原来的角色资源
        batchdeleteRoleResourceByRoleId(roleIds);

        // 批量插入行的角色
        List<RoleResource> roleResourceList = new ArrayList<>();
        for (Long roleId : roleIds) {
            for (Long resourceId : resourceIds) {
                Resource resource = resourceMapper.selectByPrimaryKey(resourceId);
                Long parentId = resource.getParentId();

                //如果resource的 parent_id!=-1 说明存在父节点，要把父节点也分配给角色直到 parent_id==-1
                while (parentId != -1L) {
                    //找到父节点
                    Resource re = resourceMapper.selectByPrimaryKey(parentId);

                    //判断父节点是不是该角色的资源
                    Example example = new Example(RoleResource.class);
                    example.createCriteria().andEqualTo("roleId", roleId);
                    example.createCriteria().andEqualTo("resourceId", re.getId());
                    List<RoleResource> rr = roleResourceMapper.selectByExample(example);
                    if (rr.isEmpty()) {
                        RoleResource roleResource = new RoleResource();
                        roleResource.fill(idGenerator.snowflakeId());
                        roleResource.setRoleId(roleId);
                        roleResource.setResourceId(parentId);

                        roleResourceList.add(roleResource);
                        parentId = re.getParentId();
                    }
                }
                RoleResource roleResource = new RoleResource();
                roleResource.fill(idGenerator.snowflakeId());
                roleResource.setRoleId(roleId);
                roleResource.setResourceId(resourceId);

                roleResourceList.add(roleResource);
            }
        }

        if (roleResourceList.isEmpty()) {
            return true;
        } else {
            int res2 = roleResourceMapper.batchInsertRoleResource(roleResourceList);
            Boolean res = res2 > 0;
            if (Boolean.FALSE.equals(res)) {
                throw new BusinessException("分配资源给角色失败");
            }
            return res;
        }
    }

    /**
     * 删除角色的所有的公司
     *
     * @param roleIds 角色id列表 不可以为空
     * @return Boolean
     */
    public  Boolean batchdeleteRoleCompanyByRoleId(@NotEmpty @Valid List<Long> roleIds) {
        if (CollectionUtils.isEmpty(roleIds)) {
            throw new BusinessException("roleIds不可以为空");
        }
        // 进行公司分配，先删除后插入
        Example example = new Example(RoleCompany.class);
        example.createCriteria().andIn("roleId", roleIds);

        int rowsAffected = roleCompanyMapper.deleteByExample(example);
        return rowsAffected > 0;
    }

    /**
     * 通过公司id查询授权公司id
     * @param companyId
     * @return
     */
    public List<Long> getAuthCompanyIdsByCompanyId(List<Long> companyId) {
        return companyMapper.getAuthCompanyIdsByCompanyId(companyId);
    }

    /**
     * 资源分配——公司
     *
     * @param roleCompanyDTO
     */
    @Transactional
    @Override
    public Boolean assignCompanyToRole(@NotNull @Valid RoleCompanyDTO roleCompanyDTO){
        // 给多个角色分配多个资源 参数去重复
        Set<Long> roleIdSet = roleCompanyDTO.getRoleIds().stream().collect(Collectors.toSet());
        List<Long> roleIds = CollectionUtils.arrayToList(roleIdSet.toArray());
        List<Long> companyId = roleCompanyDTO.getCompanyIds();
        List<Long> authCompanyIds = getAuthCompanyIdsByCompanyId(companyId);
        Set<Long> companySet = authCompanyIds.stream().collect(Collectors.toSet());
        List<Long> companyIds = CollectionUtils.arrayToList(companySet.toArray());

        idGenerator.init();

        // 删除原来的角色公司
        batchdeleteRoleCompanyByRoleId(roleIds);

        // 批量插入行的角色
        List<RoleCompany> roleCompanyList = new ArrayList<>();
        for (Long roleId : roleIds) {
            for (Long companyIdd : companyIds) {
                RoleCompany roleCompany = new RoleCompany();
                roleCompany.fill(idGenerator.snowflakeId());
                roleCompany.setRoleId(roleId);
                roleCompany.setAuthCompanyId(companyIdd);

                roleCompanyList.add(roleCompany);
            }
        }

        if (roleCompanyList.isEmpty()) {
            return true;
        } else {
            int res = roleCompanyMapper.batchInsertRoleCompany(roleCompanyList);
            Boolean result = res > 0;
            if (Boolean.FALSE.equals(result)) {
                throw new BusinessException("分配公司给角色失败");
            }
            return result;
        }
    }
}
